<template>
  <el-dialog v-dragDirectives append-to-body :close-on-click-modal="false" :title="title" :visible.sync="visibile" :width="width" :top="top" @open="open">
    <avue-crud
      ref="crud"
      :table-loading="loading"
      :data="data"
      :option="option"
      @search-change="searchChange"
      @search-reset="searchReset"
      :page.sync="page"
      @row-click="rowClick"
      @row-dblclick="rowDbclick"
      @row-del="rowDel"
      @current-change="currentChange"
      @size-change="sizeChange"
      @refresh-change="refreshChange"
    >
      <template slot="menuLeft">
        <avue-form :option="menuLeftOption" v-model="menuLeftForm" @submit="submit"> </avue-form>
        <el-button type="primary" icon="el-icon-plus" size="small" :disabled="productionOrderNoDisabled" @click="addRow">新 增</el-button>
      </template>
      <template slot="menuRight" slot-scope="{ size }">
        <el-button v-if="modalStatus == 'add'" type="primary" :size="size" :disabled="productionOrderNoDisabled" @click="startPlanEnact">开始排程</el-button>
        <el-button v-if="modalStatus == 'add'" type="primary" :size="size" :disabled="finishDisabled" @click="finishPlanEnact">完成排程</el-button>
        <el-button v-if="modalStatus == 'edit'" type="primary" :size="size" :disabled="productionOrderNoDisabled" @click="reloadPlanEnact">刷新排程</el-button>
        <el-button v-if="modalStatus == 'edit'" type="primary" :size="size" :disabled="productionOrderNoDisabled" @click="changePlanEnact">修改排程</el-button>
      </template>

      <!-- slot -->
      <template slot="workshopId" slot-scope="{ row }">
        <el-select v-if="!row.fixedData" v-model="row.workshopId" placeholder="请选择车间" @change="(value) => changeWorkshopId(value, deptList, row)">
          <el-option v-for="item in deptList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
        <span v-else>{{ row.workshopName }}</span>
      </template>
      <template slot="lineId" slot-scope="{ row }">
        <el-select v-model="row.lineId" placeholder="请选择产线" @change="(value) => changeLineId(value, lineList, row)">
          <el-option v-for="item in row.lineList && row.lineList.length > 0 ? row.lineList : lineList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
      </template>
      <template slot="processId" slot-scope="{ row }">
        <el-select v-model="row.processId" placeholder="请选择工艺流程">
          <el-option v-for="item in processList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
      </template>
      <template slot="bomId" slot-scope="{ row }">
        <el-select v-model="row.bomId" placeholder="请选择BOM版本" @change="(value) => changeBomId(value, bomList, row)">
          <el-option v-for="item in bomList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
        </el-select>
      </template>
      <template slot="lineQuantity" slot-scope="{ row }">
        <el-input-number
          v-model="row.lineQuantity"
          size="mini"
          style="width: 112px"
          controls-position="right"
          @change="handleChange"
          placeholder="请输入分配数量"
          :min="0"
          :max="maxQuantityAllotted"
        ></el-input-number>
      </template>
      <template slot="timeReadyToProduce" slot-scope="{ row }">
        <el-input-number
          v-model="row.timeReadyToProduce"
          size="mini"
          style="width: 112px"
          controls-position="right"
          @change="handleChange"
          placeholder="请输入备产时长M"
          :min="0"
        ></el-input-number>
      </template>
      <template slot="quantityForNextWo" slot-scope="{ row }">
        <el-input-number
          v-model="row.quantityForNextWo"
          size="mini"
          style="width: 112px"
          controls-position="right"
          @change="handleChange"
          placeholder="请输入工单流转数量"
          :min="0"
        ></el-input-number>
      </template>
      <template slot="timeForNextWo" slot-scope="{ row }">
        <el-input-number
          v-model="row.timeForNextWo"
          size="mini"
          style="width: 112px"
          controls-position="right"
          @change="handleChange"
          placeholder="请输入流转时长M"
          :min="0"
        ></el-input-number>
      </template>
    </avue-crud>
  </el-dialog>
</template>
<script>
import {
  savePlan,
  deletePlan,
  updatePlan,
  getWorkshop,
  planCalculating,
  getProductionPlanByProductionOrderNo,
  getLineListByProductionOrderNo,
  getBomListByProductionOrderNo,
  getProcessListByProductionOrderNo
} from '@/api/aps/planEnact';

export default {
  name: 'base-modal-template',
  props: {
    newTableData: {
      type: Array,
      default: () => []
    },
    modalStatus: {
      type: String,
      default: 'add'
    },
    visibile: {
      type: Boolean,
      default: false
    },
    config: {
      type: Object,
      default: () => {}
    },
    width: {
      type: String,
      default: '70%'
    },
    top: {
      type: String,
      default: '5vh'
    },
    title: {
      type: String,
      default: ''
    }
  },
  watch: {
    visibile(val) {
      this.visibile = val;
      this.$emit('update:visibile', val);
      if (!val) {
        this.$emit('newKey', '');
      }
    }
  },
  data() {
    return {
      productionPlanId: '',
      finishDisabled: true,
      productionOrderNoDisabled: true,
      planDetailList: [],
      maxQuantityAllotted: 0, // 最大分配数量
      deptList: [],
      lineList: [],
      processList: [],
      bomList: [],
      menuLeftOption: {
        emptyBtn: false,
        submitText: '确定',
        menuSpan: 3,
        labelWidth: 60,
        column: [
          {
            label: '订单号',
            prop: 'productionOrderNo',
            value: '',
            span: 16
          }
        ]
      },
      menuLeftForm: {
        productionOrderNo: ''
      },
      addData: {},
      visibile: false,
      loading: false,
      data: [],
      // 分页器配置
      page: {
        pageSize: 20,
        currentPage: 1,
        total: 0
      },
      option: {
        height: 250,
        calcHeight: 30,
        tip: false,
        searchShow: true,
        searchMenuSpan: 5,
        border: true,
        index: false,
        viewBtn: false,
        editBtn: false,
        delBtn: true,
        addBtn: false,
        selection: false,
        refreshBtn: false,
        columnBtn: false,
        dialogClickModal: false,
        menuWidth: 100,
        menu: true,
        labelWidth: 120,
        column: [
          {
            label: '车间',
            prop: 'workshopId',
            slot: true
          },
          {
            label: '产线',
            prop: 'lineId',
            slot: true
          },
          {
            label: '工艺流程',
            prop: 'processId',
            slot: true
          },
          {
            label: 'BOM版本',
            prop: 'bomId',
            slot: true
          },
          {
            label: '分配数量',
            prop: 'lineQuantity',
            slot: true
          },
          {
            label: '备产时长M',
            prop: 'timeReadyToProduce',
            slot: true
          },
          {
            label: '工单流转数量',
            prop: 'quantityForNextWo',
            slot: true
          },
          {
            label: '流转时长M',
            prop: 'timeForNextWo',
            slot: true
          }
        ]
      }
    };
  },
  methods: {
    open() {
      this.visibile = true;
    },
    hideModal() {
      this.visibile = false;
    },
    submit(form, done) {
      let { productionOrderNo } = form;
      done();
      if (!productionOrderNo) {
        this.$message.warning('请输入订单号');
        return;
      }
      this.onLoad(productionOrderNo);
    },
    async onLoad(productionOrderNo) {
      this.loading = true;
      this.page.total = 0;
      let productionOrderNoInfo = await this.getProductionOrderNo(productionOrderNo);
      if (!productionOrderNoInfo) {
        this.$message.error('生产订单不存在，请重新输入');
        this.loading = false;
        return;
      }
      this.productionPlanId = productionOrderNoInfo.id;
      this.maxQuantityAllotted = productionOrderNoInfo.planQuantity;
      this.data = productionOrderNoInfo.planDetailList;
      console.log(this.data);
      this.data.map(async (d) => {
        d.lineList = await this.getLine(this.menuLeftForm.productionOrderNo, d.workshopId);
        // this.lineList = await this.getLine(this.menuLeftForm.productionOrderNo, d.workshopId);
      });
      //  this.lineList = await this.getLine(this.menuLeftForm.productionOrderNo, workshopId);
      // 查询车间 查询bom 查询工艺路线 查询生产订单信息
      // 查询产线
      Promise.all([this.getDeptList(), this.getBom(productionOrderNo), this.getProcess(productionOrderNo)])
        .then((res) => {
          let [deptList, bomList, processList] = res;
          this.deptList = deptList;
          this.bomList = bomList;
          this.processList = processList;
          console.log(deptList, bomList, processList);
        })
        .catch(() => {})
        .finally(() => {
          // this.selectionClear();
          this.loading = false;
          this.productionOrderNoDisabled = false;
        });
    },
    addRow() {
      this.data.splice(0, 0, {
        lineList: []
      });
      this.finishDisabled = true;
    },
    // 开始排程
    startPlanEnact() {
      this.planDetailList = this.data.map((d) => {
        return {
          id: d.id,
          bomId: d.bomId,
          bomVersion: d.bomVersion,
          bomPartNo: d.bomPartNo,
          workshopId: d.workshopId,
          workshopName: d.workshopName,
          lineId: d.lineId,
          lineName: d.lineName,
          lineQuantity: d.lineQuantity,
          processId: d.processId,
          processCode: d.processCode,
          quantityForNextWo: d.quantityForNextWo,
          timeForNextWo: d.timeForNextWo,
          timeReadyToProduce: d.timeReadyToProduce
        };
      });
      if (!this.planDetailList || this.planDetailList.length == 0) {
        this.$message.warning('排程数据不能为空');
        return;
      }
      let checkResult = this.checkField(this.planDetailList, ['bomId', 'workshopId', 'lineId', 'processId']);
      if (!checkResult) {
        this.$message.warning('此次排程缺少BOM版本,车间,产线或工艺路线，请仔细检查提交数据');
        return;
      }
      // 校验是否有重复数据（同车间的产线只能有一条）
      let isRepetition = this.checkRepetData(this.planDetailList);
      if (isRepetition) {
        this.$message.warning('此次排程有重复的车间产线，请仔细检查提交数据');
        return;
      }
      planCalculating({
        planDetailList: this.planDetailList,
        productionOrderNo: this.menuLeftForm.productionOrderNo
      })
        .then((res) => {
          let data = res.data.data;
          this.$emit('startPlanEnact', data);
          this.$message.success('开始排程成功');
          this.finishDisabled = false;
        })
        .catch((err) => {});
    },
    // 完成排程
    finishPlanEnact() {
      let planList = this.newTableData.filter((newData) => {
        return this.planDetailList.map((p) => p.workshopId).includes(newData.workshopId) && this.planDetailList.map((p) => p.lineId).includes(newData.lineId);
      });
      if (planList && planList.length > 0) {
        planList = planList.map((plan) => {
          delete plan.planSimpleVO;
          delete plan.detailVO;
          delete plan.$index;
          delete plan['workshopName-span'];
          return plan;
        });
        savePlan({
          planDetailList: planList,
          planEndDate: planList[0].planEndDate,
          planStartDate: planList[0].planStartDate,
          productionOrderNo: this.menuLeftForm.productionOrderNo,
          productionPlanId: this.productionPlanId
        })
          .then(() => {
            this.$message.success('完成排程');
            this.$emit('update:visibile', false);
            this.$emit('refresh');
          })
          .catch(() => {});
      }
    },
    // 刷新排程
    reloadPlanEnact() {
      this.planDetailList = this.data.map((d) => {
        return {
          id: d.id,
          bomId: d.bomId,
          bomVersion: d.bomVersion,
          bomPartNo: d.bomPartNo,
          workshopId: d.workshopId,
          workshopName: d.workshopName,
          lineId: d.lineId,
          lineName: d.lineName,
          processId: d.processId,
          lineQuantity: d.lineQuantity,
          quantityForNextWo: d.quantityForNextWo,
          timeForNextWo: d.timeForNextWo,
          timeReadyToProduce: d.timeReadyToProduce
        };
      });
      if (!this.planDetailList || this.planDetailList.length == 0) {
        this.$message.warning('排程数据不能为空');
        return;
      }
      let checkResult = this.checkField(this.planDetailList, ['bomId', 'workshopId', 'lineId', 'processId']);
      if (!checkResult) {
        this.$message.warning('此次排程缺少BOM版本,车间,产线或工艺路线，请仔细检查提交数据');
        return;
      }
      planCalculating({
        planDetailList: this.planDetailList,
        productionOrderNo: this.menuLeftForm.productionOrderNo
      })
        .then((res) => {
          let data = res.data.data;
          this.$emit('startPlanEnact', data);
          this.$message.success('刷新排程成功');
        })
        .catch((err) => {});
    },
    // 修改排程
    changePlanEnact() {
      let planList = this.newTableData.filter((newData) => {
        return this.planDetailList.map((p) => p.workshopId).includes(newData.workshopId) && this.planDetailList.map((p) => p.lineId).includes(newData.lineId);
      });
      if (planList && planList.length > 0) {
        planList = planList.map((plan) => {
          delete plan.planSimpleVO;
          delete plan.detailVO;
          delete plan.$index;
          delete plan['workshopName-span'];
          return plan;
        });
        updatePlan({
          planDetailList: planList,
          planEndDate: planList[0].planEndDate,
          planStartDate: planList[0].planStartDate,
          productionOrderNo: this.menuLeftForm.productionOrderNo,
          productionPlanId: planList[0].productionPlanId
        })
          .then(() => {
            this.$message.success('修改排程成功');
            this.$emit('update:visibile', false);
            this.$emit('refresh');
          })
          .catch(() => {});
      }
    },
    // 检验排程数据是否有重复提交数据
    checkRepetData(arr) {
      var hash = {};
      for (var i in arr) {
        if (hash[arr[i].workshopId] && hash[arr[i].lineId]) {
          return true;
        } else {
          hash[arr[i].workshopId] = true;
          hash[arr[i].lineId] = true;
        }
      }
      return false;
    },
    getBom(productionOrderNo) {
      return new Promise((resolve, reject) => {
        getBomListByProductionOrderNo({ productionOrderNo })
          .then((res) => {
            if (res && res.status == 200) {
              let data = res.data.data.map((d) => {
                return {
                  // label: d.bomVersion + '(' + d.bomNo + ')',
                  label: d.bomVersion,
                  value: d.id
                };
              });
              resolve(data);
            }
          })
          .catch((err) => {});
      });
    },
    getLine(productionOrderNo, workshopId) {
      return new Promise((resolve, reject) => {
        getLineListByProductionOrderNo({ productionOrderNo, workshopId })
          .then((res) => {
            if (res && res.status == 200) {
              let data = res.data.data.map((d) => {
                return {
                  label: d.name,
                  value: d.id
                };
              });
              resolve(data);
            }
          })
          .catch((err) => {});
      });
    },
    getProcess(productionOrderNo) {
      return new Promise((resolve, reject) => {
        getProcessListByProductionOrderNo({ productionOrderNo })
          .then((res) => {
            if (res && res.status == 200) {
              let data = res.data.data.map((d) => {
                return {
                  label: d.name,
                  value: d.id
                };
              });
              resolve(data);
            }
          })
          .catch((err) => {});
      });
    },
    getDeptList() {
      return new Promise((resolve, reject) => {
        getWorkshop()
          .then((res) => {
            if (res && res.status == 200) {
              let data = res.data.data.map((d) => {
                return {
                  label: d.workshopName,
                  value: d.workshopId
                };
              });
              resolve(data);
            }
          })
          .catch((err) => {});
      });
    },
    // 根据订单号查询排程计划信息 获取计划生产数量quantity/编辑时回显排程
    getProductionOrderNo(productionOrderNo) {
      return new Promise((resolve, reject) => {
        getProductionPlanByProductionOrderNo({ productionOrderNo }).then((res) => {
          if (res && res.status == 200) {
            let data = res.data.data;
            resolve(data);
          }
        });
      });
    },
    checkField(planDetailList, params) {
      return params
        .map((param) => {
          return planDetailList.every((plan) => plan[param]);
        })
        .every((item) => item);
    },
    async changeWorkshopId(workshopId, deptList, row) {
      console.log('workshopId', workshopId);
      let workshopName = deptList.filter((d) => d.value == workshopId)[0].label;
      row.workshopName = workshopName;
      this.$set(row, 'lineId', ''); // 置空产线id
      this.lineList = await this.getLine(this.menuLeftForm.productionOrderNo, workshopId);
    },
    changeLineId(value, lineList, row) {
      let lineName = '';
      let lineListData = lineList.filter((d) => d.value == value);
      if (lineListData && lineListData.length > 0) {
        lineName = lineListData[0].label;
      }
      row.lineName = lineName;
      this.$set(row, 'lineId', value);
    },
    changeBomId(value, bomList, row) {
      let bomVersion = bomList.filter((d) => d.value == value)[0].label;
      row.bomVersion = bomVersion;
    },
    rowDel(row) {
      this.$confirm('确定将选择数据删除?', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (row.id) {
          deletePlan({
            id: row.id
          }).then(() => {
            this.$message.success('删除成功');
            this.getPlanList();
          });
        } else {
          let findIndex = this.data.findIndex((d) => d.$index == row.$index);
          if (findIndex > -1) {
            this.data.splice(findIndex, 1);
            this.$message.success('删除成功');
          }
        }
        this.finishDisabled = true;
      });
    }
  }
};

// 冒泡排序
function bubbleSort(arr) {
  for (let i = 0; i < arr.length; i++) {
    for (let j = 0; j < arr.length - i - 1; j++) {
      if (arr[j].workshopId > arr[j + 1].workshopId) {
        let temp = arr[j];
        arr[j] = arr[j + 1];
        arr[j + 1] = temp;
      }
    }
  }
  return arr;
}
</script>
<style lang="scss" scoped></style>
